﻿namespace NTLib.IOC.Containers
{
    using Core.Memory;
    using Core.Pool;
    using Core.Reflection;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;

    /// <summary>
    /// 
    /// </summary>
    /// <seealso cref="NTLib.Core.Memory.Disposable" />
    /// <seealso cref="NTLib.IOC.Containers.IContainer" />
    public class TypeContainer : Disposable, IContainer
    {
        #region Fields

        private readonly Type _instanceType;
        private readonly Type _key;
        private readonly TypePool _pool;

        #endregion

        #region Ctor

        /// <summary>
        /// Initializes a new instance of the <see cref="TypeContainer"/> class.
        /// </summary>
        public TypeContainer(Type instance, Type key, bool usePool)
        {
            this._instanceType = instance;
            this._key = key;
            if (usePool)
                this._pool = new TypePool();
        }

        #endregion

        #region Methods

        /// <summary>
        /// Determines whether this instance can handle the specified key.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <returns>
        ///   <c>true</c> if this instance can handle the specified key; otherwise, <c>false</c>.
        /// </returns>
        public bool CanHandle(Type key)
        {
            return key.IsOrInheritOf(key);
        }

        /// <summary>
        /// Gets the specified state.
        /// </summary>
        /// <typeparam name="TInstance">The type of the instance.</typeparam>
        /// <param name="state">The state.</param>
        /// <param name="token">The token.</param>
        /// <returns></returns>
        public virtual TInstance Get<TInstance>(object state = null, CancellationToken token = default(CancellationToken))
        {
            if (this._pool != null)
                return (TInstance)this._pool.GetByType(this._instanceType);
            return (TInstance)Activator.CreateInstance(this._instanceType);
        }



        #endregion
    }
}
